package com.wcs.exam.common.util;

import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;

/**
 * 图片工具类
 *
 * @author Admin
 */
@Slf4j
public final class ImgUtil {

    private ImgUtil() {

    }

    /**
     * 下载图片Base64字符串
     *
     * @param url 图片地址
     * @return base64
     */
    public static String downloadImgBase64(String url) {
        byte[] bytes = HttpUtil.downloadBytes(url);
        return Base64.getEncoder().encodeToString(bytes).replace("\r\n", "");
    }

    /**
     * 判断图片base64字符串的文件格式
     *
     * @param imageBase64 图片Base64字符串
     * @return 图片类型
     */
    public static String getBase64Type(String imageBase64) {
        byte[] imageBytes = Base64.getDecoder().decode(imageBase64);
        //  创建字节数组输入流
        InputStream inputStream = new ByteArrayInputStream(imageBytes);
        return FileTypeUtil.getType(inputStream);
    }

    /**
     * 右下角打水印
     *
     * @see <a href="https://blog.csdn.net/u011627980/article/details/50318271">...</a>
     */
    public static void pressImage(File pressImgFile, File srcImageFile, Integer x, Integer y) throws IOException {
        Image src = ImageIO.read(srcImageFile);
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        g.drawImage(src, 0, 0, width, height, null);
        // 水印文件
        Image pressImg = ImageIO.read(pressImgFile);
        int pressImgWidth = pressImg.getWidth(null);
        int pressImgHeight = pressImg.getHeight(null);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
        g.drawImage(pressImg, x, y, pressImgWidth, pressImgHeight, null);
        // 水印文件结束
        g.dispose();
        ImageIO.write(image, "JPEG", srcImageFile);
    }


    /**
     * 图片缩放(图片等比例缩放为指定大小，空白部分以白色填充)
     *
     * @param file 图片
     * @author wcs
     */
    public static void assignImage(File file, int destWidth, int destHeight) {
        try {
            BufferedImage srcBufferedImage = ImageIO.read(file);
            int imgWidth = destWidth;
            int imgHeight = destHeight;
            int srcWidth = srcBufferedImage.getWidth();
            int srcHeight = srcBufferedImage.getHeight();
            if (srcHeight >= srcWidth) {
                imgWidth = (int) Math.round(((destHeight * 1.0 / srcHeight) * srcWidth));
            } else {
                imgHeight = (int) Math.round(((destWidth * 1.0 / srcWidth) * srcHeight));
            }
            BufferedImage destBufferedImage = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = destBufferedImage.createGraphics();
            graphics2D.setBackground(Color.WHITE);
            graphics2D.clearRect(0, 0, destWidth, destHeight);
            graphics2D.drawImage(srcBufferedImage.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH), (destWidth / 2) - (imgWidth / 2), (destHeight / 2) - (imgHeight / 2), null);
            graphics2D.dispose();
            ImageIO.write(destBufferedImage, "JPEG", file);
        } catch (IOException e) {
            log.error("处理图片失败", e);
        }
    }


    /**
     * 给图片添加文字水印
     *
     * @param pressText     水印文字
     * @param srcImageFile  源图像地址
     * @param destImageFile 目标图像地址
     * @param fontName      水印的字体名称
     * @param fontStyle     水印的字体样式，例如Font.BOLD
     * @param fontSize      水印的字体大小
     */
    public static void pressText(String pressText, File srcImageFile, File destImageFile, String fontName, int fontStyle, int fontSize) {
        try {
            Image src = ImageIO.read(srcImageFile);
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);
            g.setColor(Color.black);
            g.setFont(new Font(fontName, fontStyle, fontSize));
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
            // 在指定坐标绘制水印文字
            g.drawString(pressText, (width - (getLength(pressText) * fontSize)), (height - fontSize));
            g.dispose();
            // 输出到文件流
            ImageIO.write(image, "JPEG", destImageFile);
        } catch (Exception e) {
            throw new UtilException(e);
        }
    }

    /**
     * 计算text的长度（一个中文算两个字符）
     *
     * @param text 文本
     * @return 字符长度，如：text="中国",返回 2；text="test",返回 2；text="中国ABC",返回 4.
     */
    private static int getLength(String text) {
        int length = 0;
        for (int i = 0; i < text.length(); i++) {
            if ((text.charAt(i) + "").getBytes().length > 1) {
                length += 2;
            } else {
                length += 1;
            }
        }
        return length / 2;
    }
}
